<template>
  <div class="container">
    <!-- 左侧面板：串口通信 -->
    <div class="left-panel">
      <h1>电子秤</h1>
      <button @click="connectPort" :disabled="isConnected">连接串口</button>
      <button @click="disconnectPort" :disabled="!isConnected">断开连接</button>
      <div class="input-group">
        <input
          type="text"
          v-model="inputData"
          placeholder="输入要发送的数据"
          :disabled="!isConnected"
        />
        <button @click="sendData" :disabled="!isConnected">发送</button>
      </div>
      <div class="output">
        <h2>接收数据：</h2>
        <div class="action-buttons">
          <button @click="clearOutput">清空</button>
          <button 
            @click="saveData" 
            :disabled="tableData.length === 0"
            class="save-btn"
          >
            保存数据
          </button>
        </div>
        <pre>{{ outputData }}</pre>
      </div>
    </div>


    <!-- 右侧面板：表格 -->
    <div class="right-panel">
      <h2>数据表格</h2>
      <table>
        <thead>
          <tr>
            <th>序号</th>
            <th>数据内容</th>
            <th>时间</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in tableData" :key="index">
            <td>{{ index + 1 }}</td>
            <td>{{ item.data }}</td>
            <td>{{ item.timestamp }}</td>
          </tr>
        </tbody>
      </table>
      <!-- 获取 JSON 数据的按钮和显示区域 -->
      <div class="json-output">
        <h2>JSON 数据</h2>
        <button @click="showJSON">获取 JSON 数据</button>
        <pre v-if="jsonData">{{ jsonData }}</pre>
      </div>
    </div>

    <div class="database-panel">
        <h2>数据库查询</h2>
        <div class="query-controls">
          <input v-model="queryKeyword" placeholder="输入查询关键词"/>
          <button @click="queryDatabase">查询</button>
          <button @click="clearQuery">重置</button>
        </div>
        <div class="table-container">
          <table>
            <thead>
              <tr>
                <th v-for="col in dbColumns" :key="col">{{ col }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(row, index) in dbData" :key="index">
                <td v-for="col in dbColumns" :key="col">{{ row[col] }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>

  </div>
</template>

<script>
export default {
  data() {
    return {
      port: null, // 串口对象
      reader: null, // 读取流
      writer: null, // 写入流
      isConnected: false, // 是否已连接
      inputData: "", // 输入的数据
      outputData: "", // 接收到的数据
      buffer: "", // 数据缓冲区
      tableData: [], // 表格数据
      jsonData: null, // JSON 格式的数据
    };
  },
  methods: {
    // 连接串口
    async connectPort() {
      if (!("serial" in navigator)) {
        alert("您的浏览器不支持 Web Serial API。");
        return;
      }

      try {
        this.port = await navigator.serial.requestPort();
        await this.port.open({ baudRate: 9600 });
        this.isConnected = true;
        this.readData(); // 开始读取数据
      } catch (error) {
        alert("连接失败: " + error.message);
      }
    },

    // 断开连接
    async disconnectPort() {
      if (this.port) {
        try {
          // 取消读取操作
          if (this.reader) {
            await this.reader.cancel();
            await this.port.readable.getReader().releaseLock();
          }

          // 取消写入操作
          if (this.writer) {
            await this.writer.close();
            await this.port.writable.getWriter().releaseLock();
          }

          // 关闭串口
          await this.port.close();
          alert("已断开连接");
        } catch (error) {
          alert("断开连接失败: " + error.message);
        } finally {
          this.isConnected = false;
          this.port = null;
          this.reader = null;
          this.writer = null;
          this.buffer = ""; // 清空缓冲区
        }
      }
    },

    // 发送数据
    async sendData() {
      if (this.port && this.inputData) {
        try {
          this.writer = this.port.writable.getWriter();
          await this.writer.write(new TextEncoder().encode(this.inputData + "\n"));
          this.writer.releaseLock();
          this.writer = null;
          this.inputData = ""; // 清空输入框
        } catch (error) {
          console.error("发送数据失败:", error);
        }
      }
    },

    // 读取数据
    async readData() {
      try {
        this.reader = this.port.readable.getReader();
        const decoder = new TextDecoder();
        while (true) {
          const { value, done } = await this.reader.read();
          if (done) break;

          // 将接收到的数据追加到缓冲区
          this.buffer += decoder.decode(value, { stream: true });

          // 检查缓冲区中是否有完整的数据行（以换行符 \n 分隔）
          const lines = this.buffer.split("\n");
          if (lines.length > 1) {
            this.outputData = "";
            // 处理完整的行
            var read_data = "";
            for (let i = 0; i < lines.length - 1; i++) {
              read_data += lines[i] + "\n"; // 显示完整的数据行
              // this.outputData += lines[i] + "\n"; // 显示完整的数据行
            }
            this.outputData = read_data;
            console.log(read_data);
            var read_data_list = read_data.split(" ");
            const filteredList = read_data_list.filter(item => item !== '' && item !== '\r\n');
            var final_data = "";
            for (let i = 0; i < filteredList.length - 1; i++) {
              final_data += filteredList[i] + "\n"; // 显示完整的数据行
            }
            this.outputData = filteredList[0] + filteredList[1]
            this.tableData.push({
                data: filteredList[0],
                timestamp: new Date().toLocaleTimeString(), // 添加时间戳
              });
            console.log(read_data.split(" "));
            console.log("DDDD")
            console.log(filteredList);
            // 保留未处理完的部分
            this.buffer = lines[lines.length - 1];
          }
        }
      } catch (error) {
        console.error("读取数据失败:", error);
      } finally {
        if (this.reader) {
          this.reader.releaseLock();
          this.reader = null;
        }
      }
    },
    // 清空输出数据
    clearOutput() {
      this.outputData = ""; // 清空接收到的数据
      this.tableData = []; // 清空表格数据
    },
    // 显示 JSON 数据
    showJSON() {
      this.jsonData = this.getTableDataAsJSON();
    },

    // 获取表格数据的 JSON 格式
    getTableDataAsJSON() {
      return JSON.stringify(this.tableData, null, 2); // 格式化输出
    },
    // 保存数据到JSON文件
  saveData() {
    if (this.tableData.length === 0) return;
    
    const jsonString = JSON.stringify(this.tableData, null, 2);
    const blob = new Blob([jsonString], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `serial-data-${new Date().toISOString().slice(0,10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
  },
  },
};
</script>

<style>
/* 样式保持不变 */
body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  display: flex; /* 使用 Flexbox 布局 */
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 1000px; /* 增加宽度以适应两列布局 */
}

.left-panel {
  flex: 1; /* 左侧面板占据剩余空间 */
  padding-right: 20px; /* 右侧留出间距 */
  border-right: 1px solid #ccc; /* 添加分割线 */
}

.right-panel {
  flex: 1; /* 右侧面板占据剩余空间 */
  padding-left: 20px; /* 左侧留出间距 */
  border-right: 1px solid #ccc; /* 添加分割线 */
}
.database-panel {
  flex: 1; /* 右侧面板占据剩余空间 */
  padding-left: 20px; /* 左侧留出间距 */
}

h1 {
  margin-bottom: 20px;
}

button {
  padding: 10px 20px;
  margin: 5px;
  border: none;
  border-radius: 5px;
  background-color: #007bff;
  color: white;
  cursor: pointer;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.input-group {
  margin: 20px 0;
  display: flex;
  justify-content: space-between;
}

input {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  width: 70%;
}

.output {
  text-align: left;
  margin-top: 20px;
}

pre {
  background-color: #f8f9fa;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  max-height: 200px;
  overflow-y: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

th, td {
  padding: 10px;
  border: 1px solid #ccc;
  text-align: left;
}

th {
  background-color: #f8f9fa;
}
.json-output {
  margin-top: 20px;
}

.json-output pre {
  background-color: #f8f9fa;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  max-height: 200px;
  overflow-y: auto;
}

.action-buttons {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
}

button.save-btn {
  background-color: #28a745;
}

button.save-btn:disabled {
  background-color: #ccc;
}
</style>